import React, { useEffect, useMemo, useState } from 'react';
import _ from 'lodash';
import { nanoid } from 'nanoid';
import { Button, Drawer, Empty, message, Spin, Tree } from 'antd';
import DebounceWrapper from '@/components/DebounceWrapper';
import { fetchDepartmentList } from '@/services/system/department';
import { fetchRoleDepartmentRelation, updateRoleDepartmentRelation } from '@/services/system/role';
import { formatTree } from '@/utils/utils';
import styles from './roleDepartmentRelationDrawer.less';

const checkStrictly = true; // 机构关联角色时，机构父子节点是否不关联（2022.10.25 存在争议，暂且就按费费设计的来）
const DebounceButton = DebounceWrapper(Button);
// 获取所有节点id集合
const getNodeIds = (tree = [], arr = []) => {
  if (!tree.length) return [];
  _.forEach(tree, (item) => {
    if (item.children && item.children.length) {
      arr.push(item.key);
      getNodeIds(item.children, arr);
    } else {
      arr.push(item.key);
    }
  });
  return arr;
};
// 获取子节点Id集合
const getChildIds = (tree = [], arr = []) => {
  if (!tree.length) return [];
  _.forEach(tree, (item) => {
    if (item.children && item.children.length) {
      getChildIds(item.children, arr);
    } else {
      arr.push(item.key);
    }
  });
  return arr;
};
// 获取父节点Id集合
const getFatherIds = (tree = [], arr = []) => {
  if (!tree.length) return [];
  _.forEach(tree, (item) => {
    if (item.children && item.children.length) {
      arr.push(item.key);
      getFatherIds(item.children, arr);
    }
  });
  return arr;
};

export default ({ visible, roleId, closeDrawer }) => {
  const [initialLoading, setInitialLoading] = useState(true);
  const [departmentTree, setDepartmentTree] = useState([]);
  const [relationLoadingId, setRelationLoadingId] = useState('');
  const [checkedKeys, setCheckedKeys] = useState([]);
  const [halfCheckedKeys, setHalfCheckedKeys] = useState([]);
  const [actionLoading, setActionLoading] = useState(false);

  const { validDepartmentIds, validDepartmentChildIds, validDepartmentFatherIds } = useMemo(
    () => ({
      validDepartmentIds: getNodeIds(departmentTree),
      validDepartmentChildIds: getChildIds(departmentTree),
      validDepartmentFatherIds: getFatherIds(departmentTree),
    }),
    [departmentTree],
  );

  // 获取机构节点列表
  const getOrganTree = async () => {
    try {
      const res = await fetchDepartmentList({ size: -1, current: 1 });
      return _.isArray(res)
        ? formatTree(res, ({ organName, id, address }) => ({
            key: id,
            title: organName,
            description: address || '',
          }))
        : [];
    } catch (e) {
      return [];
    }
  };
  // 获取角色关联的机构列表
  const getRoleDepartmentRelation = async (roleId) => {
    try {
      const res = await fetchRoleDepartmentRelation({ roleId });
      return _.isArray(res) ? res : [];
    } catch (e) {
      return [];
    }
  };

  // 初始化
  useEffect(() => {
    getOrganTree().then((treeData) => {
      setDepartmentTree(treeData);
      setInitialLoading(false);
    });
  }, []);
  useEffect(() => {
    if (!_.isEmpty(departmentTree)) {
      if (visible) {
        const nextRelationLoadingId = nanoid(12);
        setRelationLoadingId(nextRelationLoadingId);
        getRoleDepartmentRelation(roleId).then((checkedIds) => {
          let validDataFetch;
          setRelationLoadingId((currentId) => {
            if (currentId === nextRelationLoadingId) {
              validDataFetch = true;
              return '';
            }
            return currentId;
          });
          if (validDataFetch) {
            // 排除机构节点删除之前授权的id
            if (checkStrictly) {
              const nextCheckedKeys = _.filter(checkedIds, (id) =>
                _.includes(validDepartmentIds, id),
              );
              setCheckedKeys(nextCheckedKeys);
            } else {
              const nextCheckedKeys = _.filter(checkedIds, (id) =>
                _.includes(validDepartmentChildIds, id),
              );
              const nextHalfCheckedKeys = _.filter(checkedIds, (id) =>
                _.includes(validDepartmentFatherIds, id),
              );
              setCheckedKeys(nextCheckedKeys);
              setHalfCheckedKeys(nextHalfCheckedKeys);
            }
          }
        });
        return;
      }
      setCheckedKeys([]);
      setHalfCheckedKeys([]);
      setRelationLoadingId('');
    }
  }, [visible, departmentTree]);

  // 交互勾选
  const handleCheck = (checkedInfo, extraCheckedInfo) => {
    if (checkStrictly) {
      const { checked } = checkedInfo;
      setCheckedKeys(checked);
    } else {
      const { halfCheckedKeys: nextHalfCheckedKeys } = extraCheckedInfo;
      setCheckedKeys(checkedInfo);
      setHalfCheckedKeys(nextHalfCheckedKeys);
    }
  };

  const handleCancel = () => {
    if (!actionLoading) {
      closeDrawer();
    }
  };
  const handleConfirm = () => {
    setActionLoading(true);
    const params = { roleId, organList: _.concat(checkedKeys, halfCheckedKeys) };
    console.log('入参：', params);
    updateRoleDepartmentRelation(params)
      .then(() => {
        closeDrawer();
        setActionLoading(false);
        message.success('角色机构关联关系更新成功');
      })
      .catch(() => {
        setActionLoading(false);
      });
  };

  return (
    <Drawer
      visible={visible}
      title={
        <div className={styles.drawerTitle}>
          角色关联机构
          {!!checkStrictly && (
            <div className={styles.drawerSubTitle}>
              角色可关联给任意机构节点(机构父子节点不再关联)
            </div>
          )}
        </div>
      }
      bodyStyle={{ paddingBottom: 80 }}
      onClose={handleCancel}
      footer={
        <div className={styles.drawerFooterButtonContainer}>
          <DebounceButton
            disabled={actionLoading}
            onClick={handleCancel}
            style={{ marginRight: 8 }}
          >
            取消
          </DebounceButton>
          <DebounceButton
            onClick={handleConfirm}
            type="primary"
            loading={actionLoading}
            disabled={initialLoading || !!relationLoadingId}
          >
            确定
          </DebounceButton>
        </div>
      }
    >
      <Spin spinning={initialLoading || !!relationLoadingId} tip="加载中...">
        {departmentTree.length ? (
          <Tree
            checkable
            checkStrictly={checkStrictly}
            defaultExpandAll
            treeData={departmentTree}
            onCheck={handleCheck}
            checkedKeys={checkedKeys}
            titleRender={({ key, title, description }) => {
              return (
                <span key={key} title={description} className={styles.treeNodeTitle}>
                  <span className={styles.treeNodeTitleText}>{title}</span>
                </span>
              );
            }}
          />
        ) : (
          <Empty description={'暂无数据'} />
        )}
      </Spin>
    </Drawer>
  );
};
